package com.wwcom.darteagle.data;

import java.util.ArrayList;
import java.util.List;

import com.wwcom.darteagle.model.DartStats;
import com.wwcom.darteagle.model.Leg;
import com.wwcom.darteagle.model.Match;
import com.wwcom.darteagle.model.MatchInfo;
import com.wwcom.darteagle.model.MatchLegs;
import com.wwcom.darteagle.model.MatchPlayer;
import com.wwcom.darteagle.model.MatchSets;
import com.wwcom.darteagle.model.Player;
import com.wwcom.darteagle.model.Set;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public class DartEagleDatabase {
    private static final int DATABASE_VERSION = 4;
    private static final String DATABASE_NAME = "darteagle";
    
    private SQLiteDatabase database;
    private PlayerObject playerObj;
    private MatchObject matchObj;
    private MatchInfoObject matchInfoObj;
    private DartStatsObject dartStatsObj;
	
    public DartEagleDatabase(Context context) {
    	DatabaseOpenHelper doh= new DatabaseOpenHelper(context);
    	database= doh.getWritableDatabase();
    	playerObj= new PlayerObject(database);
    	matchObj= new MatchObject(database);
    	matchInfoObj= new MatchInfoObject(database);
    	dartStatsObj= new DartStatsObject(database);
    }
    
    public void close()
    {
        if(database != null) {
            if(database.isOpen())
            	database.close();
        }
    }    

    //players interface
    public Player getPlayer(long playerId) {
    	return playerObj.get(playerId);
    }

    public Player getPlayer(String playerName) {
    	return playerObj.get(playerName);
    }

    public void addPlayer(Player player) {
    	playerObj.add(player);
    }
    
    public List<Player> getPlayers() {
    	return playerObj.getPlayers();
    }

    //match interface
    public boolean isResumableMatchInDatabase() {
    	return matchObj.resumableExists();
    }
    
    public Match getResumableMatch() {
    	return matchObj.getResumable();
    }
    
    public Match getMatch(long id) {
    	return matchObj.get(id);
    }
    
    public void insertMatch(Match m) {
    	matchObj.insert(m);
    }
    
    public void deleteAllResumableMatches() {
    	matchObj.deleteAllResumable();
    }
    
    public List<MatchInfo> getPlayerMatchInfos(String playerName) {
    	return matchInfoObj.getPlayerMatchInfos(playerName);
    }

    //dart stats interface
    public List<DartStats> getPlayerDartStats(Player player) {
    	return dartStatsObj.get(player);
    }
    
    // get a match containing all players statistics
    public Match getPlayerOverallMatch(Player player) {
    	List<DartStats> dsList= getPlayerDartStats(player);

    	//make output dartstats 
    	MatchInfo mi= new MatchInfo();
    	mi.addMatchPlayer(player);
    	mi.setNumLegs(0);
    	mi.setNumSets(0);
    	DartStats dsOut= new DartStats(mi,mi.getMatchPlayers().get(0),-1,-1);

    	// merge them all together
    	int nLegs= 0;
    	int nSets= 0;
    	for (DartStats ds : dsList) {
    		dsOut.merge(ds);
    		nLegs+= ds.getMatchPlayer().getNumLegs();
    		nSets+= ds.getMatchPlayer().getNumSets();
    		//load sets data here to get number of legs won in each set
    		if (ds.getMatchInfo().getNumSets()>0) {
    			Match m= matchObj.get(ds.getMatchInfo().getId());
    			for (Set s : m.getSets()) {
    				Log.d("DartEagleDatabase","Set");
	    			for (Leg l : s.getLegs()) {
	    				if (l.getLegWinner() != null &&
	    						l.getLegWinner().getPlayer().getName().equals(player.getName())) {
	    	    			nLegs++;   					
	    				}
	    			}
    			}
    		}
    	}    	
    	dsOut.getMatchPlayer().setNumLegs(nLegs);
    	dsOut.getMatchPlayer().setNumSets(nSets);
    	
    	Match m= new Match(mi);
    	m.startPlaying();
    	List<DartStats> dsListOut= new ArrayList<DartStats>();
    	dsListOut.add(dsOut);
    	m.setPlayerStats(dsListOut);
    	return m;
    	
    }
    
    //Database management
	private class DatabaseOpenHelper extends SQLiteOpenHelper {
	
	    DatabaseOpenHelper(Context context) {
	        super(context, DATABASE_NAME, null, DATABASE_VERSION);
	    }
	
	    @Override
	    public void onCreate(SQLiteDatabase db) {
			String sql= PlayerObject.createSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);
			
	    	sql= MatchObject.createSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);

	    	sql= MatchInfoObject.createSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);
	    	
	    	sql= VisitScoreObject.createSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);

	    	sql= DartStatsObject.createSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);
	    
	    }
	
		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.d("DartEagleDatabase","onUpgrade oldVersion: "+oldVersion+", newVersion: "+newVersion);
			if (oldVersion <= newVersion) {
				db.beginTransaction();
				try {
					String sql = PlayerObject
							.upgradeSQL(oldVersion, newVersion);
					if (sql != null) {
						db.execSQL(sql);
					}
					sql = MatchObject.upgradeSQL(oldVersion, newVersion);
					if (sql != null) {
						db.execSQL(sql);
					}
					sql = MatchInfoObject.upgradeSQL(oldVersion, newVersion);
					if (sql != null) {
						db.execSQL(sql);
					}
					sql = VisitScoreObject.upgradeSQL(oldVersion, newVersion);
					if (sql != null) {
						db.execSQL(sql);
					}
					sql = DartStatsObject.upgradeSQL(oldVersion, newVersion);
					if (sql != null) {
						db.execSQL(sql);
					}
					db.setTransactionSuccessful();
				} catch (SQLException s) {
					
				}
				db.endTransaction();
			} else {
				// clear db and recreate on downgrades
				clearDatabase(db);
				onCreate(db);
			}
		}
		
	    private void clearDatabase(SQLiteDatabase db) {
			String sql= PlayerObject.deleteSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);
			
	    	sql= MatchObject.deleteSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);

	    	sql= MatchInfoObject.deleteSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);
	    	
	    	sql= VisitScoreObject.deleteSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);

	    	sql= DartStatsObject.deleteSQL();	    	
	    	if (sql != null)
	    		db.execSQL(sql);
	    
	    }
		
	
	}
}
